/**
 * Class: OpenLayers.Layer.WeGoogle
 * A class to exploring Google map
 * 
 * Inherits from:
 *  - <OpenLayers.Layer.XYZ>
 */
OpenLayers.Layer.WeGoogle = OpenLayers.Class(OpenLayers.Layer.XYZ, {
    attribution: "Image &copy; <a href=http://maps.google.com/ target=_blank>Google Maps</a>",
    sphericalMercator: true,
    wrapDateLine: true,
    logoControl: null,
    
    initialize: function(name, url, options) {
        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, arguments);
        
        this.events.register('visibilitychanged', this, this.onVisibilityChanged);
        this.logoControl = new OpenLayers.Control({displayClass: 'olLayerGooglePoweredBy'});
    },
    
    destroy: function() {
        this.logoControl.destroy();
        this.logoControl = null;
        
        OpenLayers.Layer.XYZ.prototype.destroy.apply(this, arguments);
    },
    
    getURL: function(bounds) {
        var res = this.map.getResolution();
        var x = Math.round((bounds.left - this.maxExtent.left) 
            / (res * this.tileSize.w));
        var y = Math.round((this.maxExtent.top - bounds.top) 
            / (res * this.tileSize.h));
        var z = this.map.getZoom() + this.zoomOffset;
        
        var limit = Math.pow(2, z);
        if (this.wrapDateLine) {
           x = ((x % limit) + limit) % limit;
        }

        var url = this.url;
        var s = '' + x + y + z;
        if (url instanceof Array)
        {
            url = this.selectUrl(s, url);
        }
        
        var path = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z});

        return path;
    },
    
    clone: function(obj) {
        if (obj == null) {
            obj = new OpenLayers.Layer.WeGoogle(this.name, this.url, this.getOptions());
        }
        obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);
        return obj;
    },
    
    afterAdd: function() {
        OpenLayers.Layer.XYZ.prototype.afterAdd.apply(this, arguments);
        
        if (this.map) {
            this.map.addControl(this.logoControl);
        }
        
        if (this.getVisibility()) {
            if (this.logoControl && this.logoControl.div) {
                this.logoControl.div.style.display = '';
            }
        } else {
            if (this.logoControl && this.logoControl.div) {
                this.logoControl.div.style.display = 'none';
            }
        }
    },
    
    onVisibilityChanged: function(evt) {
        if (this.getVisibility()) {
            if (this.logoControl && this.logoControl.div) {
                this.logoControl.div.style.display = '';
            }
        } else {
            if (this.logoControl && this.logoControl.div) {
                this.logoControl.div.style.display = 'none';
            }
        }
    },
    
    CLASS_NAME: "OpenLayers.Layer.WeGoogle"
});

// A class to exploring Google street map
OpenLayers.Layer.WeGoogle.Street = OpenLayers.Class(OpenLayers.Layer.WeGoogle, {
    url: [
        'http://mt0.google.com/vt/lyrs=m@169000000&x=${x}&y=${y}&z=${z}&s=Galileo',
        'http://mt1.google.com/vt/lyrs=m@169000000&x=${x}&y=${y}&z=${z}&s=Galileo'
    ],
    
    initialize: function(name, url, options) {
        OpenLayers.Layer.WeGoogle.prototype.initialize.apply(this, arguments);
        this.name = name ? name : OpenLayers.i18n('WeGoogleMap_name');
    },
    
    CLASS_NAME: "OpenLayers.Layer.WeGoogle.Street"
});

// A class to exploring Google satellite map
OpenLayers.Layer.WeGoogle.Satellite = OpenLayers.Class(OpenLayers.Layer.WeGoogle, {
    url: [
        'http://khm0.google.com/kh/v=125&src=app&x=${x}&y=${y}&z=${z}&s=Galileo',
        'http://khm1.google.com/kh/v=125&src=app&x=${x}&y=${y}&z=${z}&s=Galileo',
        'http://khm2.google.com/kh/v=125&src=app&x=${x}&y=${y}&z=${z}&s=Galileo',
        'http://khm3.google.com/kh/v=125&src=app&x=${x}&y=${y}&z=${z}&s=Galileo'
    ],
    
    initialize: function(name, url, options) {
        OpenLayers.Layer.WeGoogle.prototype.initialize.apply(this, arguments);
        this.name = name ? name : OpenLayers.i18n('WeGoogleSatellite_name');
    },
    
    // when the satellite layer is not visible, the toponym should be hide too
    onVisibilityChanged: function(evt) {
        OpenLayers.Layer.WeGoogle.prototype.onVisibilityChanged.apply(this, arguments);
        
        var googleToponyms = this.map.getLayersByClass('OpenLayers.Layer.WeGoogle.Toponym');
        for (var i=0; i<googleToponyms.length; i++) {
            googleToponyms[i].setVisibility(this.getVisibility());
        }
    },
    
    CLASS_NAME: "OpenLayers.Layer.WeGoogle.Satellite"
});

// A class to exploring Google place name
OpenLayers.Layer.WeGoogle.Toponym = OpenLayers.Class(OpenLayers.Layer.WeGoogle, {
    isBaseLayer: false,
    visibility: false, // hide default
    url: [
        'http://mt0.google.com/vt/lyrs=h@169000000&x=${x}&y=${y}&z=${z}&s=Galileo',
        'http://mt1.google.com/vt/lyrs=h@169000000&x=${x}&y=${y}&z=${z}&s=Galileo'
    ],
    
    initialize: function(name, url, options) {
        OpenLayers.Layer.WeGoogle.prototype.initialize.apply(this, arguments);
        this.name = name ? name : OpenLayers.i18n('WeGoogleToponym_name');
    },
    
    CLASS_NAME: "OpenLayers.Layer.WeGoogle.Toponym"
});

// A class to exploring Google terrian map
OpenLayers.Layer.WeGoogle.Terrian = OpenLayers.Class(OpenLayers.Layer.WeGoogle, {
    url: [
        'http://mt0.google.com/vt/lyrs=t@128,r@169000000&x=${x}&y=${y}&z=${z}&s=Galileo',
        'http://mt1.google.com/vt/lyrs=t@128,r@169000000&x=${x}&y=${y}&z=${z}&s=Galileo'
    ],
    
    initialize: function(name, url, options) {
        OpenLayers.Layer.WeGoogle.prototype.initialize.apply(this, arguments);
        this.name = name ? name : OpenLayers.i18n('WeGoogleTerrian_name');
    },
    
    CLASS_NAME: "OpenLayers.Layer.WeGoogle.Terrian"
});

